結構如下
<template>
  <main class="min-h-screen grid place-items-center">
    <section class="w-full max-w-[560px] space-y-6 sm:space-y-8 text-center">
      <!-- 顯示時間 -->
      <div class="mx-auto w-full max-w-[340px] sm:max-w-[420px]">
        <div class="mb-3 grid place-items-center">
          <div class="px-3.5 py-1.5 rounded-full bg-white/70 backdrop-blur-sm">
            <div class="text-3xl md:text-4xl font-semibold">
              {{ fmt() }}
            </div>
          </div>
        </div>
        <!-- 呼吸球 + 進度圈 -->
        <div class="relative">
          <ThreeBreathingSphere />
          <div class="progress-ring" :style="{ '--progress': (progress*360) + 'deg' }"></div>
        </div>
      </div>
      <!-- 停止 -->
      <button @click="handleStop" class="stop-btn">STOP</button>
    </section>
  </main>
</template>
結構如下
// 場景初始化
const initScene = () => {
  scene = new THREE.Scene()
  camera = new THREE.PerspectiveCamera(32, 1, 0.1, 100)
  camera.position.set(0, 0, 9)
  const sphereGeo = new THREE.SphereGeometry(2.4, 128, 128)
  const sphereMat = new THREE.MeshPhysicalMaterial({
    color: new THREE.Color(0.2, 0.5, 1.0),
    roughness: 0.01,
    metalness: 0.05,
    transmission: 0.99,
    thickness: 1.2,
    clearcoat: 1.0,
    clearcoatRoughness: 0.01,
    ior: 1.6,
    reflectivity: 0.95,
    iridescence: 0.9,
    iridescenceIOR: 1.6
  })
  mainSphere = new THREE.Mesh(sphereGeo, sphereMat)
  scene.add(mainSphere)
}
// 動畫
const animate = () => {
  requestAnimationFrame(animate)
  const t = Date.now() * 0.001
  const breath = Math.sin(t * 0.5) * 0.1 + 1.0
  mainSphere.scale.set(breath, breath, breath) // 呼吸
  mainSphere.rotation.x = t * 0.1
  mainSphere.rotation.y = t * 0.15
  renderer.render(scene, camera)
}
展示畫面如下,還有一些地方要修改(像是裡面的球在放大時、沒有完整顯示)